package com.huanlis.cloud.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;

/**
 * 鉴权服务器配置
 *
 * @author lihuan
 * @since 2022/10/5 22:58
 */
@Configuration
@EnableAuthorizationServer
public class OauthServerConfiguration extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security
                .allowFormAuthenticationForClients()
                .checkTokenAccess("isAuthenticated()");
//                .tokenKeyAccess("isAuthenticated()");
    }

    /**
     * 配置客户端服务器认证方式
     *
     * @author lihuan
     * @since 2023/10/19 17:25
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("source_user")
                .secret(passwordEncoder.encode("client_secret"))
                // Oauth2四周授权码模式：
                //     authorization_code 授权码模式，最安全。需要第三方确认授权后才能获取AccessToken。
                //     implicit 简化模式，不需要第三方授权，直接可以获取accessToken。
                //     password 用户名密码模式，直接使用用户名和密码获取accessToken；
                //     client_credentials 客户端模式
                .authorizedGrantTypes("authorization_code", "refresh_token", "implicit", "password", "client_credentials")
                .scopes("all")
                .resourceIds("source_user", "source_consumer", "source_provider")
                // 自动同意
                .autoApprove(true)
                .redirectUris("http://localhost:8001/api/oauth/code", "http://www.baidu.com")
        ;
        // 自己配置客服端查询服务
//        clients.withClientDetails(new ClientDetailsService() {
//            @Override
//            public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
//                BaseClientDetails baseClientDetails = new BaseClientDetails();
//                baseClientDetails.setClientId("source_user");
//                baseClientDetails.setClientSecret(passwordEncoder.encode("client_secret"));
//                baseClientDetails.setResourceIds(Collections.singleton("source_user"));
//                HashSet<String> authorizedGrantTypes = new HashSet<>(5);
//                authorizedGrantTypes.add("authorization_code");
//                authorizedGrantTypes.add("refresh_token");
//                authorizedGrantTypes.add("implicit");
//                authorizedGrantTypes.add("password");
//                authorizedGrantTypes.add("client_credentials");
//                baseClientDetails.setAuthorizedGrantTypes(authorizedGrantTypes);
//                baseClientDetails.setScope(Collections.singleton("all"));
//                HashSet<String> redirectUris = new HashSet<String>(2);
//                redirectUris.add("http://localhost:8001/api/oauth/code");
//                redirectUris.add("http://www.baidu.com");
//                baseClientDetails.setRegisteredRedirectUri(redirectUris);
//                return baseClientDetails;
//            }
//        });
    }


    /**
     * 配置认证断点的问题
     *
     * @author lihuan
     * @since 2023/10/30 17:58
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints
                // 支持用户名密码模式
                .authenticationManager(authenticationManager);
    }
}
